/**
 * @file Any.hpp
 * @author 1102403684@qq.com
 * @brief 通用类设计 
 * @version 0.1
 * @date 2024-10-02
 * 
 * @copyright Copyright (c) 2024
 * 
 */

#pragma once
#include <algorithm>

class Any
{
public:
    Any() : content_(nullptr) {}
    template <typename T>
    Any(const T &val) : content_(new PlaceHolder<T>(val)) {}
    Any(const Any &any) : content_(any.content_ ? any.content_->clone() : nullptr) {}
    ~Any()
    {
        if (content_ != nullptr)
            delete content_;
    }
    Any &swap(Any &any)
    {
        std::swap(content_, any.content_);
        return *this;
    }

    // 返回子类对象保存数据的指针
    template <typename T>
    T *get()
    {
        if (!content_ || typeid(T) != content_->type())
            return nullptr;

        return &(static_cast<PlaceHolder<T> *>(content_)->value_);
    }

    template <typename T>
    Any &operator=(const T &val)
    {
        Any(val).swap(*this);
        return *this;
    }

    Any &operator=(const Any &any)
    {
        Any(any).swap(*this);
        return *this;
    }
 
private:
    class Holder
    {
    public:
        virtual ~Holder() {};
        virtual const std::type_info& type() = 0;
        virtual Holder *clone() = 0;
    };

    template <typename T>
    class PlaceHolder : public Holder
    {
    public:
        PlaceHolder(const T &val) : value_(val) {}
        virtual const std::type_info& type() { return typeid(T); }
        virtual Holder *clone() { return new PlaceHolder(value_); }
        T value_;
    };

private:
    Holder *content_;
};